package cn.virens.web.components.open.wxmp.session;

import java.util.Map;

import com.alibaba.fastjson.JSON;

import cn.virens.web.components.open.session.WxSession;
import cn.virens.web.components.open.session.WxSessionManager;
import me.chanjar.weixin.mp.bean.message.HardWare;
import me.chanjar.weixin.mp.bean.message.ScanCodeInfo;
import me.chanjar.weixin.mp.bean.message.SendLocationInfo;
import me.chanjar.weixin.mp.bean.message.SendPicsInfo;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;

/**
 * 微信Session包装的消息体
 * 
 * @author virens
 */
public class WxMpSessionMessage extends WxMpXmlMessage {
	private static final long serialVersionUID = -922914355378995537L;

	private final Map<String, Object> attribute;
	private final WxMpXmlMessage instance;
	private final String appid;

	private WxSession session;

	public WxMpSessionMessage(WxMpXmlMessage instance, Map<String, Object> attribute, String appid) {
		this.attribute = attribute;
		this.instance = instance;
		this.appid = appid;
	}

	public String getAppid() {
		return appid;
	}

	@SuppressWarnings("unchecked")
	public <T> T getAttr(T key) {
		return (T) attribute.get(key);
	}

	@SuppressWarnings("unchecked")
	public <T> T putAttr(String key, T value) {
		return (T) attribute.put(key, value);
	}

	/**
	 * 保存session
	 * 
	 * @param sessionManager Session管理器
	 */
	public void putSession(WxSessionManager sessionManager) {
		if (session != null && sessionManager != null) {
			sessionManager.putSession(getFromUser(), session);
		}
	}

	/**
	 * 获取Session(如果不存在会创建)
	 * 
	 * @param  sessionManager Session管理器
	 * @return
	 */
	public WxSession getSession(WxSessionManager sessionManager) {
		return getSession(sessionManager, true);
	}

	/**
	 * 获取Session
	 * 
	 * @param  sessionManager Session管理器
	 * @return
	 */
	public synchronized WxSession getSession(WxSessionManager sessionManager, boolean create) {
		if (sessionManager != null && (session == null || session.isExpired())) {
			return session = sessionManager.getSession(getFromUser(), create);
		} else {
			return session;
		}
	}

	@Override
	public Map<String, Object> getAllFieldsMap() {
		return instance.getAllFieldsMap();
	}

	@Override
	public String getBizMsgMenuId() {
		return instance.getBizMsgMenuId();
	}

	@Override
	public String getCardId() {
		return instance.getCardId();
	}

	@Override
	public String getCity() {
		return instance.getCity();
	}

	@Override
	public String getConsumeSource() {
		return instance.getConsumeSource();
	}

	@Override
	public String getContent() {
		return instance.getContent();
	}

	@Override
	public String getCountry() {
		return instance.getCountry();
	}

	@Override
	public String getCreateOrderTime() {
		return instance.getCreateOrderTime();
	}

	@Override
	public Long getCreateTime() {
		return instance.getCreateTime();
	}

	@Override
	public String getDesc() {
		return instance.getDesc();
	}

	@Override
	public String getDescription() {
		return instance.getDescription();
	}

	@Override
	public String getDetail() {
		return instance.getDetail();
	}

	@Override
	public String getDeviceId() {
		return instance.getDeviceId();
	}

	@Override
	public Integer getDeviceStatus() {
		return instance.getDeviceStatus();
	}

	@Override
	public String getDeviceType() {
		return instance.getDeviceType();
	}

	@Override
	public Integer getErrorCount() {
		return instance.getErrorCount();
	}

	@Override
	public String getEvent() {
		return instance.getEvent();
	}

	@Override
	public String getEventKey() {
		return instance.getEventKey();
	}

	@Override
	public Long getExpiredTime() {
		return instance.getExpiredTime();
	}

	@Override
	public String getExtInfo() {
		return instance.getExtInfo();
	}

	@Override
	public String getFailReason() {
		return instance.getFailReason();
	}

	@Override
	public Long getFailTime() {
		return instance.getFailTime();
	}

	@Override
	public String getFee() {
		return instance.getFee();
	}

	@Override
	public Integer getFilterCount() {
		return instance.getFilterCount();
	}

	@Override
	public String getFormat() {
		return instance.getFormat();
	}

	@Override
	public String getFreeCoinCount() {
		return instance.getFreeCoinCount();
	}

	@Override
	public String getFriendUserName() {
		return instance.getFriendUserName();
	}

	@Override
	public String getFromKfAccount() {
		return instance.getFromKfAccount();
	}

	@Override
	public String getFromUser() {
		return instance.getFromUser();
	}

	@Override
	public HardWare getHardWare() {
		return instance.getHardWare();
	}

	@Override
	public String getIsChatRoom() {
		return instance.getIsChatRoom();
	}

	@Override
	public Integer getIsGiveByFriend() {
		return instance.getIsGiveByFriend();
	}

	@Override
	public String getIsRecommendByFriend() {
		return instance.getIsRecommendByFriend();
	}

	@Override
	public String getIsRestoreMemberCard() {
		return instance.getIsRestoreMemberCard();
	}

	@Override
	public String getIsReturnBack() {
		return instance.getIsReturnBack();
	}

	@Override
	public String getKeyStandard() {
		return instance.getKeyStandard();
	}

	@Override
	public String getKeyStr() {
		return instance.getKeyStr();
	}

	@Override
	public String getKfAccount() {
		return instance.getKfAccount();
	}

	@Override
	public String getLabel() {
		return instance.getLabel();
	}

	@Override
	public Double getLatitude() {
		return instance.getLatitude();
	}

	@Override
	public String getLocationId() {
		return instance.getLocationId();
	}

	@Override
	public String getLocationName() {
		return instance.getLocationName();
	}

	@Override
	public Double getLocationX() {
		return instance.getLocationX();
	}

	@Override
	public Double getLocationY() {
		return instance.getLocationY();
	}

	@Override
	public Double getLongitude() {
		return instance.getLongitude();
	}

	@Override
	public String getMediaId() {
		return instance.getMediaId();
	}

	@Override
	public String getMemo() {
		return instance.getMemo();
	}

	@Override
	public Long getMenuId() {
		return instance.getMenuId();
	}

	@Override
	public String getModifyBalance() {
		return instance.getModifyBalance();
	}

	@Override
	public String getModifyBonus() {
		return instance.getModifyBonus();
	}

	@Override
	public String getMsg() {
		return instance.getMsg();
	}

	@Override
	public Long getMsgId() {
		return instance.getMsgId();
	}

	@Override
	public String getMsgType() {
		return instance.getMsgType();
	}

	@Override
	public String getOldUserCardCode() {
		return instance.getOldUserCardCode();
	}

	@Override
	public Integer getOpType() {
		return instance.getOpType();
	}

	@Override
	public String getOpenId() {
		return instance.getOpenId();
	}

	@Override
	public String getOrderId() {
		return instance.getOrderId();
	}

	@Override
	public String getOrderStatus() {
		return instance.getOrderStatus();
	}

	@Override
	public String getOrderType() {
		return instance.getOrderType();
	}

	@Override
	public String getOriginalFee() {
		return instance.getOriginalFee();
	}

	@Override
	public Integer getOuterId() {
		return instance.getOuterId();
	}

	@Override
	public String getOuterStr() {
		return instance.getOuterStr();
	}

	@Override
	public String getPayCoinCount() {
		return instance.getPayCoinCount();
	}

	@Override
	public String getPayFinishTime() {
		return instance.getPayFinishTime();
	}

	@Override
	public String getPicUrl() {
		return instance.getPicUrl();
	}

	@Override
	public String getPoiId() {
		return instance.getPoiId();
	}

	@Override
	public Double getPrecision() {
		return instance.getPrecision();
	}

	@Override
	public String getProductId() {
		return instance.getProductId();
	}

	@Override
	public String getProvince() {
		return instance.getProvince();
	}

	@Override
	public String getReason() {
		return instance.getReason();
	}

	@Override
	public String getReasonMsg() {
		return instance.getReasonMsg();
	}

	@Override
	public String getReceiptInfo() {
		return instance.getReceiptInfo();
	}

	@Override
	public String getRecognition() {
		return instance.getRecognition();
	}

	@Override
	public String getRefundFreeCoinCount() {
		return instance.getRefundFreeCoinCount();
	}

	@Override
	public String getRefundPayCoinCount() {
		return instance.getRefundPayCoinCount();
	}

	@Override
	public String getRefuseReason() {
		return instance.getRefuseReason();
	}

	@Override
	public String getRegionCode() {
		return instance.getRegionCode();
	}

	@Override
	public String getRemarkAmount() {
		return instance.getRemarkAmount();
	}

	@Override
	public String getResult() {
		return instance.getResult();
	}

	@Override
	public Double getScale() {
		return instance.getScale();
	}

	@Override
	public ScanCodeInfo getScanCodeInfo() {
		return instance.getScanCodeInfo();
	}

	@Override
	public String getScene() {
		return instance.getScene();
	}

	@Override
	public SendLocationInfo getSendLocationInfo() {
		return instance.getSendLocationInfo();
	}

	@Override
	public SendPicsInfo getSendPicsInfo() {
		return instance.getSendPicsInfo();
	}

	@Override
	public Integer getSentCount() {
		return instance.getSentCount();
	}

	@Override
	public String getSessionId() {
		return instance.getSessionId();
	}

	@Override
	public String getSex() {
		return instance.getSex();
	}

	@Override
	public String getSkuInfo() {
		return instance.getSkuInfo();
	}

	@Override
	public String getStaffOpenId() {
		return instance.getStaffOpenId();
	}

	@Override
	public String getStatus() {
		return instance.getStatus();
	}

	@Override
	public String getStoreUniqId() {
		return instance.getStoreUniqId();
	}

	@Override
	public Long getSuccTime() {
		return instance.getSuccTime();
	}

	@Override
	public String getThumbMediaId() {
		return instance.getThumbMediaId();
	}

	@Override
	public String getTicket() {
		return instance.getTicket();
	}

	@Override
	public String getTitle() {
		return instance.getTitle();
	}

	@Override
	public String getToKfAccount() {
		return instance.getToKfAccount();
	}

	@Override
	public String getToUser() {
		return instance.getToUser();
	}

	@Override
	public Integer getTotalCount() {
		return instance.getTotalCount();
	}

	@Override
	public String getTransId() {
		return instance.getTransId();
	}

	@Override
	public String getUnionId() {
		return instance.getUnionId();
	}

	@Override
	public String getUrl() {
		return instance.getUrl();
	}

	@Override
	public String getUserCardCode() {
		return instance.getUserCardCode();
	}

	@Override
	public String getVerifyCode() {
		return instance.getVerifyCode();
	}

	@Override
	public String toString() {
		return JSON.toJSONString(instance.getAllFieldsMap());
	}

	@Override
	public int hashCode() {
		return instance.hashCode();
	}

	@Override
	public boolean equals(Object o) {
		return instance.equals(o);
	}

}
